class UnionFind {
  public:
	UnionFind(int n) {
		for (int i = 0; i < n; ++i)
			parent.push_back(i);
	}

	void Union(int x, int y) {
		int rootx = find(x);
		int rooty = find(y);
		if (rootx != rooty) {
			parent[rootx] = rooty;
		}
	}
	vector<int> parent;

  private:
	int find(int x) {
		if (x != parent[x])
			parent[x] = find(parent[x]);
		return parent[x];
	}
};

int findCircleNum(vector<vector<int>> &isConnected) {

	auto n = isConnected.size();
	UnionFind unionFind(n);
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			if (isConnected[i][j])
				unionFind.Union(i, j);
	int count = 0;
	for (int i = 0; i < n; ++i)
		if (i == unionFind.parent[i])
			count++;
	return count;
}
